﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace UpdateDbLogWatch
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            dataGridView.AllowDrop = true;
        }

        private void ImportToolLabel_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = false;
            var result = openFileDialog.ShowDialog();
            if (result != DialogResult.OK)
            {
                return;
            }
            var fileName = openFileDialog.FileName;
            parserLogFile(fileName);
        }

        private void parserLogFile(string fileName)
        {
            Thread thread = new Thread(() =>
            {
                BeginInvoke(new MethodInvoker(() =>
                {
                    Text = fileName;
                    msgLb.Visible = true;
                }));

                var logInfo = new QueryLogInfo();
                logInfo.Parser(fileName);

                BeginInvoke(new MethodInvoker(() =>
                {
                    msgLb.Visible = false;
                }));

                if (logInfo.DataTable.Rows.Count <= 0)
                {
                    MessageBox.Show("Not suport file:" + fileName);
                    return;
                }

                TimeSpan queryTime = TimeSpan.Zero;

                foreach (DataRow row in logInfo.DataTable.Rows)
                {
                    queryTime = queryTime.Add(TimeSpan.Parse(row["QueryTime"].ToString()));
                }

                BeginInvoke(new MethodInvoker(() =>
                {
                    dataGridView.DataSource = logInfo.DataTable;
                    
                    queryCountLb.Text = logInfo.DataTable.Rows.Count.ToString();
                    queryTimeLb.Text = queryTime.ToString("c");
                    dbmodsTimeLb.Text = logInfo.DbModsTime.ToString("c");

                    beginTimeLb.Text = logInfo.BeginTime.ToString("u");
                    endTimeLb.Text = logInfo.EndTime.ToString("u");
                    totalTimeLb.Text = logInfo.TotalTime.ToString("c");

                    maxScriptLengthLb.Text = logInfo.MaxScriptLength.ToString();
                    otherTimeLb.Text = (logInfo.TotalTime - queryTime - logInfo.DbModsTime).ToString("g");

                }));
            });
            thread.IsBackground = true;
            thread.Start();
        }

        private void dataGridView_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
        {
            e.SortResult = DateTime.Compare(DateTime.Parse(e.CellValue1.ToString()), DateTime.Parse(e.CellValue2.ToString()));
            if (e.SortResult == 0 && e.Column.Name != "ExecuteTime")
            {
                e.SortResult = DateTime.Compare(DateTime.Parse(dataGridView.Rows[e.RowIndex1].Cells["ExecuteTime"].Value.ToString()), DateTime.Parse(dataGridView.Rows[e.RowIndex2].Cells["ExecuteTime"].Value.ToString()));
            }

            e.Handled = true;
        }

        private void dataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0)
            {
                return;
            }
            DataGridViewRow row = ((DataGridView) sender).Rows[e.RowIndex];
            ScriptInfoFrom.ShowScriptInfo(row.Cells[e.ColumnIndex].Value.ToString());
        }

        private void dataGridView_DragDrop(object sender, DragEventArgs e)
        {
            var paths = (string[])e.Data.GetData(DataFormats.FileDrop);
            var logPath = paths[0];
            parserLogFile(logPath);

        }

        private void dataGridView_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.All;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }
    }

    public class QueryLogInfo
    {
        public DataTable DataTable { get; set; }
        public DateTime BeginTime { get; set; }
        public DateTime EndTime { get; set; }
        public TimeSpan DbModsTime { get; set; }

        public int MaxScriptLength { get; set; }

        public TimeSpan TotalTime
        {
            get
            {
                return EndTime - BeginTime;
            }
        }

        public QueryLogInfo()
        {
            DataTable = new DataTable();
            DataTable.Columns.Add("ExecuteTime");
            DataTable.Columns.Add("QueryTime");
            DataTable.Columns.Add("QueryScript");
        }

        public bool Parser(string fileName)
        {
            if (!File.Exists(fileName))
            {
                return false;
            }
            
            var allText = File.ReadAllText(fileName);
            
            var queryRegex = new Regex(@"(?<time>\d{1,4}/\d{1,2}/\d{1,2} \d{1,2}:\d{1,2}:\d{1,2})\W{0,2}--Query-Script:(?<script>[\s\S]*?)--Query-Time:(?<timespan>.*)");

            var matches = queryRegex.Matches(allText);

            MaxScriptLength = 0;

            foreach (Match match in matches)
            {
                var executeTime = match.Groups["time"].Value;
                var queryScript = match.Groups["script"].Value.Trim();
                var queryTime = match.Groups["timespan"].Value.Trim();

                DataTable.Rows.Add(executeTime, queryTime, queryScript);

                if (queryScript.Length > MaxScriptLength)
                {
                    MaxScriptLength = queryScript.Length;
                }
            }


            
            var beginRegex = new Regex(@"(?<beginRegex>.*): UpdateDB - begin");
            var beginQuery = new Regex(@"\n(?<beginQuery>.*): GetInsertContentStatement - begin");
            var endRegex = new Regex(@"\n(?<endRegex>.*): UpdateDB - end");

           

            var beginMatch = beginRegex.Match(allText);

            if (beginMatch.Success)
            {
                BeginTime = DateTime.Parse(beginMatch.Groups["beginRegex"].Value);
            }

            var beginQueryMatch = beginQuery.Match(allText);

            if (beginQueryMatch.Success)
            {
                DbModsTime = DateTime.Parse(beginQueryMatch.Groups["beginQuery"].Value) - BeginTime;
            }

            var endMatch = endRegex.Match(allText.Substring(allText.Length-100));

            if (endMatch.Success)
            {
                EndTime = DateTime.Parse(endMatch.Groups["endRegex"].Value);
            }

            return true;
        }
    }
}
